﻿using System;
using System.Collections.Generic;
using System.Text;
using MathNet.Numerics.LinearAlgebra;

namespace BarStructures.Analysers
{
    public static class ElementHelper
    {
        public static Matrix GetGlobalStiffness6DMatrix(Bar bar)
        {
            Matrix mx = GetTransform6DMatrix(bar, false).Multiply(GetLocalStiffness6DMatrix(bar)).
                Multiply(GetTransform6DMatrix(bar, true));

            return mx;
        }

        public static Matrix GetLocalStiffness6DMatrix(Bar bar)
        {
            double EAL = bar.Phys.E * bar.Phys.A / bar.Length;
            double EI = bar.Phys.E * bar.Phys.I;
            double L =  1 / bar.Length;
            double L2 =  L * L;
            double L3 = L2 * L;

            double[][] mx = new double[6][] { 
                new double[6] { EAL,   0,             0,            -EAL,   0,             0},
                new double[6] { 0,     12 * EI * L3,  6 * EI * L2,   0,    -12 * EI * L3,  6 * EI * L2},
                new double[6] { 0,     6 * EI * L2,   4 * EI * L,    0,    -6 * EI * L2,   2 * EI * L},
                new double[6] {-EAL,   0,             0,             EAL,   0,             0},
                new double[6] { 0,    -12 * EI * L3, -6 * EI * L2,   0,     12 * EI * L3, -6 * EI * L2},
                new double[6] { 0,     6 * EI * L2,   2 * EI * L,    0,    -6 * EI * L2,   4 * EI * L}};

            return new Matrix(mx);
        }

        public static Matrix GetGlobalDescreteMass6DMatrix(Bar bar)
        {
            Matrix mx = GetTransform6DMatrix(bar, false).Multiply(GetLocalDescreteMass6DMatrix(bar)).
                Multiply(GetTransform6DMatrix(bar, true));

            return mx;
        }

        public static Matrix GetLocalDescreteMass6DMatrix(Bar bar)
        {
            double m = 0.1 * bar.Phys.Density * bar.Phys.A * bar.Length / 2;

            double[][] mx = new double[6][] { 
                new double[6] { m, 0, 0, 0, 0, 0},
                new double[6] { 0, m, 0, 0, 0, 0},
                new double[6] { 0, 0, 0, 0, 0, 0},
                new double[6] { 0, 0, 0, m, 0, 0},
                new double[6] { 0, 0, 0, 0, m, 0},
                new double[6] { 0, 0, 0, 0, 0, 0}};

            return new Matrix(mx);
        }

        public static Matrix GetTransform6DMatrix(Bar bar, bool transposed)
        {
            double c = bar.Cos;
            double s = bar.Sin;

            double[][] tm = new double[6][];
            if (!transposed)
            {
                tm[0] = new double[6] { c, -s, 0, 0,  0, 0 };
                tm[1] = new double[6] { s,  c, 0, 0,  0, 0 };
                tm[2] = new double[6] { 0,  0, 1, 0,  0, 0 };
                tm[3] = new double[6] { 0,  0, 0, c, -s, 0 };
                tm[4] = new double[6] { 0,  0, 0, s,  c, 0 };
                tm[5] = new double[6] { 0,  0, 0, 0,  0, 1 };
            }
            else
            {
                tm[0] = new double[6] {  c, s, 0,  0, 0, 0 };
                tm[1] = new double[6] { -s, c, 0,  0, 0, 0 };
                tm[2] = new double[6] {  0, 0, 1,  0, 0, 0 };
                tm[3] = new double[6] {  0, 0, 0,  c, s, 0 };
                tm[4] = new double[6] {  0, 0, 0, -s, c, 0 };
                tm[5] = new double[6] {  0, 0, 0,  0, 0, 1 };
            }

            return new Matrix(tm);
        }
    }
}
